package com.xAdmin.util;


import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: xiaYZ 2025/1/29
 * @version: 1.0
 */
public class TreeUtil {

    /**
     * 构建树状数据
     *
     * @param allNodes 所有节点列表
     * @param idFieldName 节点ID字段名，如：id
     * @param parentIdFieldName 父节点ID字段名，如：parentId
     * @param childrenFieldName 子节点集合字段名，如：children
     * @param <T> 节点类型
     * @return 树状数据列表
     */
    public static <T> List<T> buildTree(List<T> allNodes, String idFieldName, String parentIdFieldName, String childrenFieldName) {
        Map<Object, T> nodeMap = new HashMap<>();
        for (T node : allNodes) {
            Object id = getField(node, idFieldName);
            nodeMap.put(id, node);
        }

        List<T> rootNodes = new ArrayList<>();

        for (T currentNode : allNodes) {
            Object parentId = getField(currentNode, parentIdFieldName);
            if (parentId == null || parentId.equals(0)) {
                rootNodes.add(currentNode);
            } else {
                T parentNode = nodeMap.get(parentId);
                if (parentNode != null) {
                    @SuppressWarnings("unchecked")
                    List<T> children = (List<T>) getField(parentNode, childrenFieldName);
                    if (children == null) {
                        children = new ArrayList<>();
                        setField(parentNode, childrenFieldName, children);
                    }
                    children.add(currentNode);
                }
            }
        }

        return rootNodes;
    }

    private static <T> Object getField(T instance, String fieldName) {
        try {
            Field field = instance.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            return field.get(instance);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            LogUtil.error("构建{}类树状数据报错", instance);
            return null;
        }
    }

    private static <T> void setField(T instance, String fieldName, Object value) {
        try {
            Field field = instance.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(instance, value);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            LogUtil.error("构建{}类树状数据报错", instance);
        }
    }
}
